﻿package com.webex.mirage;

import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.robochina.airobot.tank.Bot;
import org.robochina.airobot.tank.Bullet;
import org.robochina.airobot.tank.FireAction;
import org.robochina.airobot.tank.HitRobotAction;
import org.robochina.airobot.tank.MessageReceivedAction;
import org.robochina.airobot.tank.RobotDeathAction;
import org.robochina.airobot.tank.RoundBeginAction;
import org.robochina.airobot.tank.SimpleRobot;
import org.robochina.airobot.tank.TickAction;
import org.robochina.math.MathUtils;

import com.webex.util.BaseBullet;
import com.webex.util.PatternMatchFire;
import com.webex.util.TankCommon;

public class MirageRobot extends SimpleRobot {

	public static final String ROLL_COMMANDER = "Commander";
	public static final String ROLL_WARRIOR = "Warrior";

	public static final String GROUP_1 = "G1";
	public static final String GROUP_2 = "G2";

	public Map targetMap = null;

	private double beginAngle = 0.0;
	private double angle_step = 0.0;

	protected final double attach_radius = 150.0;
	protected final double radius_of_fire = 70.0;
	protected final double radius_fire_target = 5.0;
	protected double distance_between_target = 0.0;
	protected double angle_with_target = 0.0;

	protected int commanderId = -1;// 当前领导坦克的Id，用于确定死亡的坦克是否是Commander

	Point2D[] lockedLocation = new Point2D[5];
	Point2D[] lockedFireLocation = new Point2D[5];

	protected PatternMatchFire pmf = new PatternMatchFire();
	protected double power = MAX_POWER;

	protected Point2D targetLocation = null;
	protected Point2D targetFireLocation = null;

	private String group = null;

	// 目标坦克
	protected Bot target = null;

	// 子弹列表
	protected List bullets = new ArrayList();

	// 当前的角色: Commander or Warrior
	protected String roll = ROLL_WARRIOR;

	public Bot getTarget() {
		return this.target;
	}
	
	
	protected Bot selectTarget(String groupId){
		List friends = getTeammates();
		List enemys = this.getAliveOppnents();
		double[] distances = new double[enemys.size()];
		double min_distance = Double.MAX_VALUE;
		
		int emenySize=enemys.size();
		
		if (emenySize==1){
			return (Bot) enemys.get(0);
		}
		
		
		List aliveTeammaters=this.getAliveTeammaters();
		boolean needExclude=false;
		if (aliveTeammaters!=null){
			for (int i=0;i<aliveTeammaters.size();i++){
				Bot teamMater=(Bot)aliveTeammaters.get(i);
				String anotherGroupId=this.getGroupID(teamMater.getName());
				if (!groupId.equals(anotherGroupId)){
					needExclude=true;
				}
			}
		}
		
		for (int iE = 0; iE < emenySize; iE++) {

			double totalDistance = 0.0;
			Bot enemy = (Bot) enemys.get(iE);
			if (!isAlive(enemy)) {
				continue;
			}
			
			int currentEnemy=enemy.getId();
			
			
			int exclutdeTarget=0;
			if (GROUP_1.equals(groupId)){
				exclutdeTarget= ((Integer) targetMap.get(GROUP_2)).intValue();
				
			}
			
			if (GROUP_2.equals(groupId)){
				exclutdeTarget= ((Integer) targetMap.get(GROUP_1)).intValue();
			}
			
			
			
			if (currentEnemy != exclutdeTarget ||(currentEnemy == exclutdeTarget && needExclude==false)) {
				
				String selfBotName=getSelfBot().getName();
				if (this.getGroupID(selfBotName).equals(groupId)){
					totalDistance += TankCommon.distance(getSelfBot(), enemy);
				}
				
				for (int iF = 0; iF < friends.size(); iF++) {
					Bot friend = (Bot) friends.get(iF);
					String groupName=this.getGroupID(friend.getName());
					if(!groupId.equals(groupName)){
						continue;
					}
					if (!isAlive(friend)) {
						continue;
					}
					totalDistance += TankCommon.distance(enemy, friend);
				}

				if (totalDistance < min_distance) {
					min_distance = totalDistance;
					target = enemy;
				}
				
			}

			
		}
		return target;
	}
	
	/**
	 * 选择进攻目标
	 * 
	 * @author angusl
	 */	
	protected Bot selectTarget() {
		List friends = getTeammates();
		List enemys = getOpponents();
		double[] distances = new double[enemys.size()];
		double min_distance = Double.MAX_VALUE;

		for (int iE = 0; iE < enemys.size(); iE++) {

			double totalDistance = 0.0;
			Bot enemy = (Bot) enemys.get(iE);
			if (!isAlive(enemy)) {
				continue;
			}

			totalDistance += TankCommon.distance(getSelfBot(), enemy);
			for (int iF = 0; iF < friends.size(); iF++) {
				Bot friend = (Bot) friends.get(iF);
				if (!isAlive(friend)) {
					continue;
				}
				totalDistance += TankCommon.distance(enemy, friend);
			}

			if (totalDistance < min_distance) {
				min_distance = totalDistance;
				target = enemy;
			}
		}
		return target;
	}

	protected Bot selectTarget(Bot deathTarget,boolean isNearest) {
		Bot bestTarget = null;
		List enemys =this.getAliveOppnents() ;
		int enemyLength=enemys.size();
		if (deathTarget == null ) {
			bestTarget = this.selectTarget();

		} else if (enemyLength==1){
			bestTarget=(Bot)enemys.get(0);
		}else {
			int exclutdeTarget1 = ((Integer) targetMap.get(GROUP_1))
					.intValue();
			int exclutdeTarget2 = ((Integer) targetMap.get(GROUP_2))
					.intValue();

			
			if (enemys != null) {
				double min_distance=0;
			
				if (isNearest){
					min_distance = Double.MAX_VALUE;
				}
				
				for (int i = 0; i < enemys.size(); i++) {
					Bot tempTarget = (Bot) enemys.get(i);
					int tempBotId = tempTarget.getId();
					if (tempBotId != exclutdeTarget1
							&& tempBotId != exclutdeTarget2) {
						double tempDistance = TankCommon.distance(
								deathTarget, tempTarget);
						if (isNearest){
							if (tempDistance < min_distance) {
								min_distance = tempDistance;
								bestTarget = tempTarget;
							}
						}else{
							if (tempDistance > min_distance) {
								min_distance = tempDistance;
								bestTarget = tempTarget;
							}
						}
						
					}
				}
			}
		}

		

		return bestTarget;
	}

	/**
	 * 每时间片触发的事件
	 */
	public void onTick(TickAction action) {
		beginAngle += angle_step;
		pmf.record(getOpponents());
		updateBullets();

		if(group == null){
			assignGroup();
		}
		
		if (commanderId == -1 && isCommander()) {
			commanderId = getSelf();
		}

		if (commanderId != -1 && !isCommander() && !isCommandAlive()) {
			amINextCommander();
		}
		//pmf.record(getAliveOppnents());
		//选择目标坦克
		scanTarget();
		//判断近距离是否有敌方坦克
		scanEnemys();
		//开火
		fireTarget();
		
		super.onTick(action);
	}

	protected void fireTarget() {
		if (target != null) {
			// 计算和目标之间的距离，及角度
			distance_between_target = MathUtils.distance(getLocation(), target
					.getLocation());
			angle_with_target = MathUtils.heading(getLocation(), target
					.getLocation());

			Point2D[] targetLocationArray = lockTarget(target);
			Point2D[] targetFireLocationArray = lockTargetFirePoint(target);
			String myName = getName().trim();
			myName = myName.substring(myName.indexOf(".") + 1);
			if (myName.equalsIgnoreCase("Commander")) {
				targetLocation = targetLocationArray[0];
				targetFireLocation = targetFireLocationArray[0];
				//group = GROUP_1;
			} else if (myName.equalsIgnoreCase("SoldierA")) {
				targetLocation = targetLocationArray[1];
				targetFireLocation = targetFireLocationArray[1];
				//group = GROUP_1;
			} else if (myName.equalsIgnoreCase("SoldierB")) {
				targetLocation = targetLocationArray[2];
				targetFireLocation = targetFireLocationArray[2];
				//group = GROUP_1;
			} else if (myName.equalsIgnoreCase("SoldierC")) {
				targetLocation = targetLocationArray[3];
				targetFireLocation = targetFireLocationArray[3];
				//group = GROUP_2;
			} else if (myName.equalsIgnoreCase("SoldierD")) {
				targetLocation = targetLocationArray[4];
				targetFireLocation = targetFireLocationArray[4];
				//group = GROUP_2;
			}
			if (distance_between_target >= attach_radius) {
				moveTo(getDestination());
				
				Bot ne = getNeastEnemy();
				double d = MathUtils.distance(getLocation(), ne.getLocation());
				if(d>300){
					power = 1.5;
					patternfire(ne);
				}else{
					power = 3;
					fireLine(ne);
				}
//			}
//			if (distance_between_target >= attach_radius && distance_between_target < 200) {
//				// 向目标移动
//				moveTo(targetLocation);
//				power = 0.5;
//				patternfire();

			} else {
				// 进入射程后计算炮弹的能力
				calPower(distance_between_target);
				// // 躲避子弹选择开火
				moveTo(targetLocation);
				power = MAX_POWER;
				fireLine(target);
			}
		}
	}

	protected void scanTarget() {
		Bot newTarget1;
		Bot newTarget2;
		if (isCommander() && targetMap != null && this.getAliveOppnents().size()>0) {
			int currentTarget1 = ((Integer) targetMap.get(GROUP_1)).intValue();
			int currentTarget2 = ((Integer) targetMap.get(GROUP_2)).intValue();
			
			
			boolean isNeedSend = false;
			
			
			
			
			
			
			if (currentTarget1 >=0) {
				newTarget1 = this.getBot(currentTarget1);

				if (!this.isAlive(newTarget1)) {
					isNeedSend = true;
					newTarget1=this.selectTarget(GROUP_1);
					if (newTarget1 !=null){
						targetMap.put(GROUP_1, newTarget1.getId());
					}
				}
			}else{
				isNeedSend=true;
				newTarget1=this.selectTarget(GROUP_1);
				if (newTarget1 !=null){
					targetMap.put(GROUP_1, newTarget1.getId());
				}
				
			}
			
			
			if (currentTarget2 > 0) {
				newTarget2 = this.getBot(currentTarget2);

				if (!this.isAlive(newTarget2)) {
					
					isNeedSend = true;
					newTarget2=this.selectTarget(GROUP_2);
					if (newTarget2 !=null){
						targetMap.put(GROUP_2, newTarget2.getId());
					}
				}
			}else{
				isNeedSend=true;
				newTarget2=this.selectTarget(GROUP_2);
				if (newTarget2 !=null){
					targetMap.put(GROUP_2, newTarget2.getId());
				}
			}
			
			if (isNeedSend) {
				String msg=newTarget1.getId() + "|" + newTarget2.getId();
				broadcastMessage(msg);
				this.assignTarget(msg);
				
			}
		}
	}

	private Point2D[] lockTarget(Bot target) {
		double origX = target.getLocation().getX();
		double origY = target.getLocation().getY();

		for (int i = 0; i < 5; i++) {
			double x = 0;
			double y = 0;
			double angle = beginAngle + i * 72;
			x = radius_of_fire * Math.cos(Math.toRadians(angle));
			y = radius_of_fire * Math.sin(Math.toRadians(angle));

			lockedLocation[i].setLocation(origX + x, origY + y);
		}

		return lockedLocation;

	}

	private Point2D[] lockTargetFirePoint(Bot target) {
		double origX = target.getLocation().getX();
		double origY = target.getLocation().getY();

		for (int i = 0; i < 5; i++) {
			if (i < 2) {
				lockedFireLocation[i] = target.getLocation();
				continue;
			}
			double x = 0;
			double y = 0;
			double angel = beginAngle + i * 120;
			x = radius_fire_target * Math.cos(Math.toRadians(angel));
			y = radius_fire_target * Math.sin(Math.toRadians(angel));

			lockedFireLocation[i].setLocation(origX + x, origY + y);
		}

		return lockedFireLocation;

	}

	private void avoidBullet() {
		List bulletSet = getBulletSet();
		List avoidedSet = filterBullets(bulletSet);
	}

	private List filterBullets(List bulletSet) {
		List avoidedSet = new ArrayList(10);
		for (Iterator iter = bulletSet.iterator(); iter.hasNext();) {
			Bullet bullet = (Bullet) iter.next();

		}
		return null;
	}

	private List getBulletSet() {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * 
	 * @author William
	 */
	private void patternfire(Bot target) {
		Point2D pos = pmf.getFirePoint(this, power, target);
		if(!anyTeammateInScope(pos)){
			fire(pmf.getFirePoint(this, power, target), power);
		}
	}

	/**
	 * 接收到队友消息时触发
	 */
	public void onMessageReceived(MessageReceivedAction action) {
		String msg = action.getMessage();
		commanderId = action.getSender();
		this.assignTarget(msg);
		super.onMessageReceived(action);
	}
	
	
   public void assignTarget(String msg){

		if (!("").equals(msg)) {
			// String command = msg.substring(0, msg.indexOf(":"));
			//msg.split("|")
			int splitLocation = msg.indexOf("|");
			int targetID1 =Integer.parseInt(msg.substring(0, splitLocation)); 
			Bot target1 = getBot(targetID1);

			int targetID2 =Integer.parseInt(msg.substring(splitLocation + 1)); 
			Bot target2 = getBot(targetID2);

			targetMap.put(GROUP_1, targetID1);
			targetMap.put(GROUP_2, targetID2);

			// TODO: select target according to Group id
			/*
			 * if (target2 != null) { this.target = target2; }
			 */

			if (GROUP_1.equals(group)) {
				this.target = target1;
			} else {
				this.target = target2;
			}
		}

	}

	/**
	 * 
	 */
	protected void updateBullets() {
		for (int i = bullets.size() - 1; i >= 0; i--) {
			BaseBullet bullet = (BaseBullet) bullets.get(i);
			if (!bullet.isValid(getTime(), getLocation()))
				bullets.remove(i);
		}
	}

	/**
	 * 任何一辆坦克开火的时候
	 */
	public void onFire(FireAction action) {
		BaseBullet bullet = new BaseBullet(action.getBullet(), getSelfBot());
		bullets.add(bullet);
		super.onFire(action);
	}

	/**
	 * 每一轮比赛开始的时候
	 */
	public void onRoundBegin(RoundBeginAction action) {
		bullets.clear();
		target = null;
		// roll = ROLL_WARRIOR;
		for (int i = 0; i < 5; i++) {
			lockedLocation[i] = new Point(0, 0);
			lockedFireLocation[i] = new Point(0, 0);
		}
		targetMap = new HashMap(2);
		targetMap.put(GROUP_1, -1);
		targetMap.put(GROUP_2, -1);
		
		pmf.ini();
	}

	public void onRobotDeath(RobotDeathAction action) {
		int deadID = action.getDied();
		Bot deadBot = getBot(deadID);
		if (isTeammate(deadBot)) {
			if (deadID == commanderId) {
				boolean nextCommander = amINextCommander();
			}
		} else {
			if (deadBot == target) {
				target = null;
			}
		}
		super.onRobotDeath(action);
	}

	/**
	 * 如果撞上坦克
	 */
	public void onHitRobot(HitRobotAction action) {
		Bot hitted = getBot(action.getHited());
		if (isTeammate(hitted)) {
			turn(Math.PI / 2);
		} else {
			fire(hitted.getLocation(), MAX_POWER);
		}
		super.onHitRobot(action);
	}

	/**
	 * 是否为Commander
	 * 
	 * @author angusl
	 * @return
	 */
	public boolean isCommander() {
		return ROLL_COMMANDER.equals(this.roll);
	}

	/**
	 * @author calviny
	 */
	public void getTargetScope(BaseBullet bullet) {
		double enemyHeading = MathUtils.heading(getLocation(), target
				.getLocation());

		double distance = MathUtils.distance(getLocation(), target
				.getLocation());

		double angle = Math.asin(attach_radius / distance);

		double minHeading = enemyHeading - angle;

		double maxHeading = enemyHeading + angle;

		double farestDist = attach_radius + distance;

		Point2D point = bullet.getLocation(getTime());

	}

	/**
	 * 判断自己是否是下一个Commander
	 * 
	 * @return
	 * @author angusl
	 */
	public boolean amINextCommander() {
		int minId = getSelf();
		List teammaters = getTeammates();
		for (int i = 0; i < teammaters.size(); i++) {
			Bot bot = (Bot) teammaters.get(i);
			if (isAlive(bot) && bot.getId() < minId) {
				// 如果有一个活着的坦克的id比自己小。退出函数
				return false;
			}
		}
		// 否则自己就是下一个Commander
		this.roll = ROLL_COMMANDER;
		return true;
	}

	/**
	 * 根据距离来确定炮弹能力的大小
	 * 
	 * @param distance
	 * @author angusl
	 */
	private void calPower(double distance) {
		power = MAX_POWER * (attach_radius - distance)
				/ (attach_radius - radius_of_fire);
	}

	/**
	 * 得到还存活的队友
	 * 
	 * @return 一个坦克的List
	 * @author angusl
	 */
	private List getAliveTeammaters() {
		List bots = new ArrayList();
		List teammates = getTeammates();
		for (int i = 0; i < teammates.size(); i++) {
			Bot teammate = (Bot) teammates.get(i);
			if (isAlive(teammate)) {
				bots.add(teammate);
			}
		}
		return bots;
	}
	
	
	private List getAliveOppnents() {
		List bots = new ArrayList();
		List teammates = this.getOpponents();
		for (int i = 0; i < teammates.size(); i++) {
			Bot teammate = (Bot) teammates.get(i);
			if (isAlive(teammate)) {
				bots.add(teammate);
			}
		}
		return bots;
	}


	/**
	 * 判断一个位置是否还在赛场内
	 * 
	 * @param pos
	 * @return True | False
	 * @author angusl
	 */
	protected boolean doesThePositioninCourt(Point2D pos) {
		double px = pos.getX();
		double py = pos.getY();
		if (px < 0 || px > getCourt().getWidth()) {
			return false;
		}
		if (py < 0 || py > getCourt().getHeight()) {
			return false;
		}
		return true;

	}

	/**
	 * 判断是否有队友在自己的射程范围内，防止误伤队友
	 * 
	 * @author angusl
	 * @return True | False
	 */
	protected boolean anyTeammateInScope(Point2D targetPos) {
		boolean hasTeammate = false;
		double distance_between_target = MathUtils.distance(getLocation(),
				targetPos);
		double heading_to_target = MathUtils.heading(getLocation(), targetPos);
		double heading_to_teammate = 0.0;
		double distance_between_teammate = 0.0;

		List aliveTeammate = getAliveTeammaters();
		for (int i = 0; i < aliveTeammate.size(); i++) {
			Bot teammate = (Bot) aliveTeammate.get(i);
			heading_to_teammate = MathUtils.heading(getLocation(), teammate
					.getLocation());
			distance_between_teammate = MathUtils.distance(getLocation(),
					teammate.getLocation());

			// 如果和队友的距离大于和目标的距离，则肯定不会伤到队友
			if (distance_between_teammate >= distance_between_target) {
				continue;
			}

			// 如果以自己为中心，队友，目标的夹角大于30度，也肯定不在设计路线上
			double angle = MathUtils.absBearing(heading_to_teammate,
					heading_to_target);
			// double angle =
			// Math.abs(MathUtils.angleDoublePI(heading_to_teammate) -
			// MathUtils.angleDoublePI(heading_to_target));
			if (angle > (Math.PI / 6)) {
				continue;
			}

			// 队友距离目标和自身连线的垂直距离
			double dis2line = distance_between_teammate * Math.sin(angle);
			if (dis2line <= this.RADIUS) {
				hasTeammate = true;
				break;
			}
		}
		return hasTeammate;
	}

	/**
	 * 判断Commander是否还存活
	 * 
	 * @return
	 */
	protected boolean isCommandAlive() {
		return isAlive(getBot(commanderId));
	}
	
	/**
	 * 以当前目标坦克的速度和角度，计算N个时间片之后的位置。近距离，短时间片效果好
	 * @param tick
	 * @return
	 */
	protected Point2D getTargetNextPostion(int tick){
		Point2D pos = new Point();
		double heading = target.getHeading();
		double velocity = target.getVelocity();
		double nextX = target.getLocation().getX() + velocity * tick * Math.cos(heading);
		double nextY = target.getLocation().getY() + velocity * tick * Math.sin(heading);
		pos.setLocation(nextX, nextY);
		return pos;
	}
	
	private void fireLine(Bot target) {
			if(target==null || !this.isAlive(target)) return;
		
			
			try {
				long time = 1;
				while(time < 25){
					
					//计算在time时间后对手的位置
					Point2D next = MathUtils.nextPoint(	target.getLocation(),
							target.getHeading(), target.getVelocity()*time);
					//判断子弹在time时间后能否打到在next位置的对手
					double distance = MathUtils.distance(next,getLocation());
					if(distance/getBulletVelocity(power)<=time && !anyTeammateInScope(next))
					{
						//能打到，迭代结束
						fire(next, power); //开火
						return;
					}
					else time++; //进入下一次迭代
				}
			} catch (Exception e) {
				println("fireLine:"+e.getMessage());
			}
			
	}
	
	protected boolean scanEnemys(){
		boolean hasEnemy = false;
		List bots = getAliveOppnents();
		for(int i =0; i< bots.size(); i++){
			Bot bot = (Bot)bots.get(i);
			double distance = MathUtils.distance(getLocation(), bot.getLocation());
			if(distance <= 30){
				fire(bot.getLocation(), MAX_POWER);
				hasEnemy = true;
				break;
			}
		}
		return hasEnemy;
	}
	
	protected void assignGroup(){
		String myName = getName().trim();
		
		myName = myName.substring(myName.lastIndexOf(".") + 1);
		if (myName.equalsIgnoreCase("Commander")) {
			group = GROUP_1;
		} else if (myName.equalsIgnoreCase("SoldierA")) {
			group = GROUP_1;
		} else if (myName.equalsIgnoreCase("SoldierB")) {
			group = GROUP_1;
		} else if (myName.equalsIgnoreCase("SoldierC")) {
			group = GROUP_2;
		} else if (myName.equalsIgnoreCase("SoldierD")) {
			group = GROUP_2;
		}
	}
	
	protected String getGroupID(String botName){
		String myName = botName.trim();
		myName = myName.substring(myName.lastIndexOf(".") + 1);
		
		String groupTemp="";
//		myName = myName.substring(myName.indexOf(".") + 1);
		if (myName.equalsIgnoreCase("Commander")) {
			groupTemp = GROUP_1;
		} else if (myName.equalsIgnoreCase("SoldierA")) {
			groupTemp = GROUP_1;
		} else if (myName.equalsIgnoreCase("SoldierB")) {
			groupTemp = GROUP_1;
		} else if (myName.equalsIgnoreCase("SoldierC")) {
			groupTemp = GROUP_2;
		} else if (myName.equalsIgnoreCase("SoldierD")) {
			groupTemp = GROUP_2;
		}
		
		return groupTemp;
	}
	
	/**
	 * 得到距离最近的一个对手
	 * @return
	 */
	protected Bot getNeastEnemy(){
		Bot bot = null;
		List bots = getAliveOppnents();
		double d = Double.MAX_VALUE;
		for(int i = 0;i < bots.size(); i++){
			Bot b = (Bot)bots.get(i);
			double d1 = MathUtils.distance(getLocation(), b.getLocation());
			if(d1< d){
				d = d1;
				bot = b;
			}
		}
		return bot;
	}
	
	//计算目标点
	private Point2D getDestination()
	{
		Point2D destination = null;
		double bestRist = Double.POSITIVE_INFINITY;
		double angle = MathUtils.heading(getLocation(), target.getLocation());
		
		for(int i=0; i < 20; i++)
		{
			double distance = MAX_MOVE_VELOCITY;
			//下一个点
			//while (distance > 0){
				Point2D next = MathUtils.nextPoint(getLocation(), (angle+ Math.toRadians(i - 10)), distance );
				//保证该点在场地中
				if(!inCourt(next)) continue;
				//比较该点的危险系数
				double rist = getRisk(next);
				if(rist<bestRist)
				{
					destination = next;
					bestRist = rist;
				}
				//distance -= 5;
				println(distance);
			//}
		}
		

		return destination;
	}
	
	private double getRisk(Point2D destination)
	{
		double rist = 0;
		for(int i=0; i<bullets.size(); i++)
		{
			BaseBullet bullet = (BaseBullet)bullets.get(i);
			Point2D bulletLocation = bullet.getLocation(getTime());
			double dis = destination.distance(bulletLocation);
			rist += 1/dis;
		}
		return rist;
	}
}
